import { app, BrowserWindow } from 'electron'
import path from 'path'
import { setTimeout } from 'timers';

//下载相关
const {dialog, ipcMain, globalShortcut} = require('electron')
const shell = require('electron').shell
const url = require('url')

let folderpath = __dirname+'\\temp';//'D:\\electron\\temp'//下载目标路径文件夹 __dirname
let downloadpath//文件下载URL
let filename//已下载文件文件名
let codetype//1:前端代码 2:后台代码 3:更新文件 4:下载并打开 5:骨架代码
let modelname//模块名称 第一个大写
let modelname_normal//模块名称
let uploadid//目录名
let projectname//项目名称
let packagename//项目名称

let mysqlhost//IP
let mysqluser//用户名
let mysqlpassword//密码
let mysqlport//端口
let mysqldatabase//数据库

let clientcodelist//前端代码复制目标路径
let servercodelist//后台代码复制目标路径

let to_version//目标更新版本号

//解压和移动相关
const fs = require('fs')
const adm_zip = require('adm-zip')
const util = require('util')

//数据库相关
const mysql  = require('mysql');

//消息
let evt

//递归删除文件夹
function deleteFolderRecursive(path) {
  if( fs.existsSync(path) ) {
      fs.readdirSync(path).forEach(function(file) {
          var curPath = path + "/" + file;
          if(fs.statSync(curPath).isDirectory()) { // recurse
              deleteFolderRecursive(curPath);
          } else { // delete file
              fs.unlinkSync(curPath);
          }
      });
      fs.rmdirSync(path);
  }
}

//查询模块列表
function initModels() {
  let connection = mysql.createConnection({
    host     : mysqlhost,
    user     : mysqluser,
    password : mysqlpassword,
    port     : mysqlport,
    database : mysqldatabase
  })
  connection.connect()
  let sql = 'SELECT LOWER(table_name) tablename,IFNULL(table_comment,"无描述") comments FROM information_schema.tables WHERE table_schema="'+mysqldatabase+'" AND table_type="base table"' // AND LOCATE("model_",table_name)>0
  connection.query(sql,[],function (err, result) {
    if(!err){
      evt.sender.send('receivelist',JSON.stringify(result))
    }
  })
  connection.end()
}

//查询模块内容
function initContents(modelname) {
  let connection = mysql.createConnection({
    host     : mysqlhost,
    user     : mysqluser,
    password : mysqlpassword,
    port     : mysqlport,
    database : mysqldatabase
  })
  connection.connect()
  let sql = " SELECT LOWER(column_name) columnName, "+
      " data_type AS dataType, "+
      " CASE WHEN data_type='int' THEN '11' WHEN data_type='tinyint' THEN '4' WHEN data_type='bigint' THEN '20' ELSE CAST(IFNULL(character_maximum_length,'') AS CHAR) END AS columnLen,"+
      " column_comment AS commentName, "+
      " CASE WHEN column_key='PRI' THEN 'PRIMARY KEY' WHEN column_key='UNI' THEN 'UNIQUE' WHEN is_nullable='Y' THEN 'NOT NULL' ELSE '' END AS 'constraintName' "+
      " FROM Information_schema.columns "+
      " WHERE table_Name = '"+modelname+"' AND table_schema='"+mysqldatabase+"'"
  connection.query(sql,[],function (err, result) {
    if(!err){
      evt.sender.send('receivecontent',JSON.stringify(result))
    }
  })
  connection.end()
}

// 下划线转换驼峰
function toHump(name) {
  return name.replace(/\_(\w)/g, function(all, letter){
      return letter.toUpperCase();
  });
}

//从项目名称获取包名称
function getPackageName(serverName){
  let _packageName = "null";
  if(serverName.indexOf("ms-base-")!=-1) {
    _packageName = serverName.replace("ms-base-", "");
  }
  if(serverName.indexOf("ma-base-")!=-1) {
    _packageName = serverName.replace("ma-base-", "");
  }
  if(serverName.indexOf("ms-")!=-1) {
    _packageName = serverName.replace("ms-", "");
  }
  if(serverName.indexOf("ma-")!=-1) {
    _packageName = serverName.replace("ma-", "");
  }
  //判断serverName是否合法
  if(_packageName=="null" || _packageName.indexOf("-")!=-1){
    return "null";
  }
  //若serverName是xxx-xxx-xxx-xxx 总返回最后一个xxx
  var arr = serverName.split("-");
  if(arr.length>2) {
    return arr[arr.length-1];
  }
  return _packageName;
}

export default class Application {
  constructor () {
    this.winURL = process.env.NODE_ENV === 'development'
      ? `http://localhost:${require('../../../config').port}`
      : `file://${__dirname}/index.html`
    this.mainWindow = undefined
  }

  createWindow () {
    this.mainWindow = new BrowserWindow({
      width: 1920,
      height: 1080,
      autoHideMenuBar:true,
      webPreferences: {webSecurity: false}
    })

    //需要删除旧文件
    ipcMain.on('init', (event, args) => {
      evt = event
      event.sender.send('tips','初始化本地环境:成功！')

      //初始化mysql参数
      var arr = args.split(",")
      mysqlhost = arr[0]
      mysqluser = arr[1]
      mysqlpassword = arr[2]
      mysqlport = arr[3]
      mysqldatabase = arr[4]
      clientcodelist = arr[5]
      servercodelist = arr[6]

      //删除临时文件
      deleteFolderRecursive(folderpath+'\\')

      //初始化模块列表
      initModels()
    })

    //测试MySQL连接
    ipcMain.on('testconn', (event, args) => {
      evt = event
      //初始化mysql参数
      var arr = args.split(",")
      var _mysqlhost = arr[0]
      var _mysqluser = arr[1]
      var _mysqlpassword = arr[2]
      var _mysqlport = arr[3]
      var _mysqldatabase = arr[4]

      //初始化模块列表
      let connection = mysql.createConnection({
        host     : _mysqlhost,
        user     : _mysqluser,
        password : _mysqlpassword,
        port     : _mysqlport,
        database : _mysqldatabase
      })
      connection.connect()
      let querySql = 'select 1 from DUAL'
      //增
      connection.query(querySql,[],function (err, result) {
        if(err){
          evt.sender.send('tips','MySQL数据库连接：失败！');
        }else{
          evt.sender.send('tips','MySQL数据库连接：成功！')
        }
      });
      connection.end();
    })

    //模块内容
    ipcMain.on('sendcontent', (event, args) => {
      initContents(args)
    })

    //软件更新
    ipcMain.on('versioncontrol', (event, args) => {
      evt = event
      var arr = args.split(",")
      let latestversion = arr[0]
      let downloadpath = arr[1]
      let json_content = fs.readFileSync(__dirname+'/version.json');
      let version_obj = JSON.parse(json_content);
      let version = version_obj.version;
      if(version!=latestversion){
        event.sender.send('tips','自动更新中，请稍侯......');
        codetype = '3';
        to_version = latestversion;
        this.mainWindow.webContents.downloadURL(downloadpath);
      }else{
        event.sender.send('tips','当前版本与指定更新版本相同：V '+version+',系统不作更改！');
      }

    })

    //下载指定文件并打开
    ipcMain.on('downloadthefile', (event, args) => {
      evt = event
      codetype = '4';//下载指定路径的文件
      this.mainWindow.webContents.downloadURL(args);
    })

    //获取当前版本
    ipcMain.on('version', (event, args) => {
      evt = event
      let json_content = fs.readFileSync(__dirname+'/version.json');
      event.sender.send('tips',json_content);

      //注册全局快捷键
      globalShortcut.unregister('CommandOrControl+I');
      globalShortcut.register('CommandOrControl+I',()=>{
        evt.sender.send('tips','openInitDialog');
      });
    })

    ipcMain.on('download', (event, args) => {
      var arr = args.split(",")
      downloadpath = arr[0]
      uploadid = downloadpath.split('codes/')[1].split('/code.zip')[0]
      codetype = arr[1]
      modelname = toHump(arr[2])
      modelname = modelname.slice(0, 1).toUpperCase() + modelname.slice(1)
      modelname_normal = arr[2]
      projectname = arr[3]
      packagename = getPackageName(projectname)
      event.sender.send('tips','开始下载......');
      this.mainWindow.webContents.downloadURL(downloadpath);
    })

    ipcMain.on('archetype', (event, args) => {
      var arr = args.split(",")
      downloadpath = arr[0]
      uploadid = downloadpath.split('codes/')[1].split('/code.zip')[0]
      codetype = arr[1]
      modelname = ''
      modelname_normal = ''
      projectname = arr[3]
      packagename = getPackageName(projectname)
      event.sender.send('tips','开始下载......');
      this.mainWindow.webContents.downloadURL(downloadpath);
    })

    //打开指定文件夹
    ipcMain.on('openfolder', (event, args) => {
      let local_folder_path = args;
      if('__dirname' == args) local_folder_path = folderpath + '\\';
      try {
        if(fs.statSync(local_folder_path).isDirectory()){
          shell.openItem(local_folder_path)
        }else if(fs.statSync(local_folder_path).isFile()){
          shell.openItem(local_folder_path)
        }else{
          event.sender.send('tips','No Such Directory:“'+local_folder_path+'”');
        }
      }catch (e) {
        if (e.code == 'ENOENT') { // no such file or directory. File really does not exist
          event.sender.send('tips','No Such Directory:“'+local_folder_path+'”');
        }
      }
    })

    this.mainWindow.webContents.session.on('will-download', (event, item, webContents) => {
      // Set the save path, making Electron not to prompt a save dialog.
      filename = item.getFilename()

      item.setSavePath(folderpath+'\\'+filename);
      item.on('updated', (event, state) => {
        if (state === 'interrupted') {
          evt.sender.send('tips','Download is interrupted but can be resumed')
        } else if (state === 'progressing') {
          if (item.isPaused()) {
            evt.sender.send('tips','Download is paused')
          } else {
            //evt.sender.send('tips','Received bytes: '+item.getReceivedBytes())
          }
        }
      })
      item.once('done', (event, state) => {
        if (state === 'completed') {
          if(codetype == '3'){
            //下载成功提示
            var unzip = new adm_zip(folderpath+'\\'+filename)
            unzip.extractAllTo(__dirname+'\\',true)
            //更新成功提示
            evt.sender.send('tips','软件更新成功，更新内容重启软件后生效')
            evt.sender.send('tips','当前版本号：V '+to_version)
            //重启软件
            setTimeout(function(){
              let filepath = app.getAppPath();
              if(filepath.indexOf('\\Contents')!=-1){//MAC系统
                shell.openItem(filepath.replace('Resources\\app','MacOS\\sgcc'));
                app.quit();
              }else{//Windows系统
                shell.openItem(filepath.replace('resources\\app','sgcc.exe'));
                app.quit();
              }
            },1500)
          }if(codetype == '4'){
            evt.sender.send('tips','下载成功，正在打开...;'+folderpath+'\\'+filename)
          }

          //如果是后端代码 并且有SQL文件 则执行SQL
          if(codetype == '2'){//后端代码

            //下载成功提示
            evt.sender.send('tips','代码下载：成功！')
            //解压缩
            var unzip = new adm_zip(folderpath+'\\'+filename)
            unzip.extractAllTo(servercodelist+'\\',true)
            evt.sender.send('tips','代码注入项目：成功！')

            setTimeout(function(){

              fs.exists(servercodelist+'\\'+packagename+'-server-dao\\src\\main\\resources\\sql\\'+modelname+'.sql',function(exists){
                if(exists){
                  fs.readFile(servercodelist+'\\'+packagename+'-server-dao\\src\\main\\resources\\sql\\'+modelname+'.sql','utf-8',function(err,data){
                    if(err){
                      evt.sender.send('tips','读取建表SQL语句：失败！')
                    }else{
                      //打印建表语句
                      evt.sender.send('tips','读取建表SQL语句：成功！')
                      //执行建表语句
                      let connection = mysql.createConnection({
                        host     : mysqlhost,
                        user     : mysqluser,
                        password : mysqlpassword,
                        port     : mysqlport,
                        database : mysqldatabase
                      })
                      connection.connect()
                      let addSql = data
                      //增
                      connection.query(addSql,[],function (err, result) {
                        if(err){
                          evt.sender.send('tips','执行建表SQL语句：失败！');
                          return;
                        }else{
                          evt.sender.send('tips','执行建表SQL语句：成功！')
                        }
                      });
                      connection.end();
                    }
                  });
                }
              })

            },1500)

          }


          //前端代码
          if(codetype == '1'){
            //下载成功提示
            evt.sender.send('tips','前端代码下载：成功！')
            //解压缩
            var unzip = new adm_zip(folderpath+'\\'+filename)
            unzip.extractAllTo(clientcodelist+'\\',true)
            evt.sender.send('tips','前端代码初始化：成功！')
          }


          if(codetype == '5'){

            //解压缩
            var unzip = new adm_zip(__dirname+'\\archetype-temp.zip')
            unzip.extractAllTo(servercodelist+'\\',true)

            //解压缩补丁包
            var unzip2 = new adm_zip(__dirname+'\\archetype-patch-ms.zip')
            unzip2.extractAllTo(servercodelist+'\\',true)

            fs.renameSync(servercodelist+'\\archetype-temp-web\\', servercodelist+'\\'+packagename+'-server-web\\');
            fs.renameSync(servercodelist+'\\archetype-temp-service\\', servercodelist+'\\'+packagename+'-server-service\\');
            fs.renameSync(servercodelist+'\\archetype-temp-dao\\', servercodelist+'\\'+packagename+'-server-dao\\');
            fs.renameSync(servercodelist+'\\archetype-temp-api\\', servercodelist+'\\'+packagename+'-server-api\\');

            // let sname = projectname.split('-')[0];
            // fs.renameSync(servercodelist+'\\'+packagename+'-server-web\\src\\main\\java\\com\\sgcc\\temp\\', servercodelist+'\\'+packagename+'-server-web\\src\\main\\java\\com\\sgcc\\'+packagename+'\\');
            // fs.renameSync(servercodelist+'\\'+packagename+'-server-service\\src\\main\\java\\com\\sgcc\\temp\\', servercodelist+'\\'+packagename+'-server-service\\src\\main\\java\\com\\sgcc\\'+packagename+'\\');
            // fs.renameSync(servercodelist+'\\'+packagename+'-server-dao\\src\\main\\java\\com\\sgcc\\temp\\', servercodelist+'\\'+packagename+'-server-dao\\src\\main\\java\\com\\sgcc\\'+packagename+'\\');
            // fs.renameSync(servercodelist+'\\'+packagename+'-server-api\\src\\main\\java\\com\\sgcc\\temp\\', servercodelist+'\\'+packagename+'-server-api\\src\\main\\java\\com\\sgcc\\'+packagename+'\\');

            //下载成功提示
            evt.sender.send('tips','骨架下载：成功！')
            //解压缩
            var unzip = new adm_zip(folderpath+'\\'+filename)
            unzip.extractAllTo(servercodelist+'\\',true)
            evt.sender.send('tips','骨架初始化：成功！')
          }


          if(codetype == '6'){

            //解压缩
            var unzip = new adm_zip(__dirname+'\\archetype-temp.zip')
            unzip.extractAllTo(servercodelist+'\\',true)

            //解压缩补丁包 新版本暂时不需要解压ma
            // var unzip2 = new adm_zip(__dirname+'\\archetype-patch-ma.zip')
            // unzip2.extractAllTo(servercodelist+'\\',true)

            fs.renameSync(servercodelist+'\\archetype-temp-web\\', servercodelist+'\\'+packagename+'-server-web\\');
            fs.renameSync(servercodelist+'\\archetype-temp-service\\', servercodelist+'\\'+packagename+'-server-service\\');

            // let sname = projectname.split('-')[0];
            // fs.renameSync(servercodelist+'\\'+packagename+'-server-web\\src\\main\\java\\com\\sgcc\\temp\\', servercodelist+'\\'+packagename+'-server-web\\src\\main\\java\\com\\sgcc\\'+packagename+'\\');
            // fs.renameSync(servercodelist+'\\'+packagename+'-server-service\\src\\main\\java\\com\\sgcc\\temp\\', servercodelist+'\\'+packagename+'-server-service\\src\\main\\java\\com\\sgcc\\'+packagename+'\\');

            //下载成功提示
            evt.sender.send('tips','骨架下载：成功！')
            //解压缩
            var unzip = new adm_zip(folderpath+'\\'+filename)
            unzip.extractAllTo(servercodelist+'\\',true)
            evt.sender.send('tips','骨架初始化：成功！')
          }

        } else {
          evt.sender.send('tips','下载包: 失败！')
        }
      })
    })

    /*/ and load the index.html of the app.
    this.mainWindow.loadURL(url.format({
      pathname: path.join(__dirname, '/app/index.html'),
      protocol: 'file:',
      slashes: true
    }))*/

    this.mainWindow.on('closed', function () {
      this.mainWindow = null
    })

    this.mainWindow.loadURL(this.winURL)
  }

  onReady () {
    this.createWindow()
  }

  registerApplicationCallback () {
    app.on('ready', this.onReady.bind(this))

    app.on('window-all-closed', () => {
      if (process.platform !== 'darwin') {
        app.quit()
      }
    })

    app.on('activate', () => {
      if (this.mainWindow === null) {
        this.createWindow()
      }
    })

    var handleStartupEvent = function () {
      if (process.platform !== 'win32') {
        return false
      }

      var squirrelCommand = process.argv[1]

      switch (squirrelCommand) {
        case '--squirrel-install':
        case '--squirrel-updated':
          install()
          return true
        case '--squirrel-uninstall':
          uninstall()
          app.quit()
          return true
        case '--squirrel-obsolete':
          app.quit()
          return true
      }

      function install () {
        var cp = require('child_process')
        var updateDotExe = path.resolve(path.dirname(process.execPath), '..', 'update.exe')
        var target = path.basename(process.execPath)
        var child = cp.spawn(updateDotExe, [
          '--createShortcut', target
        ], {detached: true})
        child.on('close', function (code) {
          app.quit()
        })
      }
      function uninstall () {
        var cp = require('child_process')
        var updateDotExe = path.resolve(path.dirname(process.execPath), '..', 'update.exe')
        var target = path.basename(process.execPath)
        var child = cp.spawn(updateDotExe, [
          '--removeShortcut', target
        ], {detached: true})
        child.on('close', function (code) {
          app.quit()
        })
      }

    }

    if (handleStartupEvent()) {

    }
  }

  run () {
    this.registerApplicationCallback()
  }
}
